
{***********************************************************}
{                                                           }
{      Informix Data Access Components                      }
{                                                           }
{      TIfxQuery component                                  }
{                                                           }
{      Copyright (c) 2001-2008 Luxena Software Company      }
{      http://www.luxena.com                                }
{      e-mail: support@luxena.com                           }
{                                                           }
{***********************************************************}

unit IfxQuery;

{$I lx.inc}

interface

uses
  Classes, DB, LXDataSetImpl, IfxTypes, IfxSQLProcessor, IfxSQL, IfxCustomDataSet;

type

{ TIfxQuery }

  TIfxQuery = class(TIfxDesignDataSet)
  private
    FParams: TParams;

    function GetSQL: TStrings;
    procedure SetSQL(Value: TStrings);
    function GetParamCount: Integer;
    procedure SetParams(Value: TParams);

    procedure ReadParamData(Reader: TReader);
    procedure WriteParamData(Writer: TWriter);

  protected
    procedure DefineProperties(Filer: TFiler); override;
    procedure SetMasterParams; override;

    { IProviderSupport }
    procedure PSExecute; override;
    function PSGetParams: TParams; override;
    procedure PSSetCommandText(const CommandText: string); override;
    procedure PSSetParams(AParams: TParams); override;

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure GetDetailLinkFields(MasterFields, DetailFields: TList); override;

    procedure ParseMacroSQL;
    function ParamByName(const Value: string): TParam;

    procedure Prepare;
    procedure Unprepare;
    function ExecSQL: int4;

    property Prepared;
    property ParamCount: Integer read GetParamCount;
    property RowsAffected;
    property Results;

  published
    property DataSource read GetDataSource write SetDataSource;
    property RequestLive;
    property SQL: TStrings read GetSQL write SetSQL;
    property ParamCheck;
    property Params: TParams read FParams write SetParams stored False;
    property UpdateObject write SetUpdateObject;
  end;


implementation


{ TIfxQuery }

constructor TIfxQuery.Create(AOwner: TComponent);
begin
  inherited;
  FParams := TParams.Create(Self);
  IfxSQL.SourceParams := FParams;
end;

destructor TIfxQuery.Destroy;
begin
  FParams.Free;
  inherited;
end;

function TIfxQuery.GetSQL: TStrings;
begin
  Result := IfxSQL.SQL;
end;

procedure TIfxQuery.SetSQL(Value: TStrings);
begin
  IfxSQL.SQL := Value;
end;

function TIfxQuery.GetParamCount: Integer;
begin
  Result := FParams.Count;
end;

procedure TIfxQuery.SetParams(Value: TParams);
begin
  FParams.AssignValues(Value);
end;

procedure TIfxQuery.ReadParamData(Reader: TReader);
begin
  Reader.ReadValue;
  Reader.ReadCollection(FParams);
end;

procedure TIfxQuery.WriteParamData(Writer: TWriter);
begin
  Writer.WriteCollection(FParams);
end;

procedure TIfxQuery.DefineProperties(Filer: TFiler);

  function WriteData: Boolean;
  begin
    if Filer.Ancestor <> nil then
      Result := not FParams.IsEqual(TIfxQuery(Filer.Ancestor).FParams) else
      Result := FParams.Count > 0;
  end;

begin
  inherited;
  Filer.DefineProperty('ParamData', ReadParamData, WriteParamData, WriteData);
end;

procedure TIfxQuery.SetMasterParams;
var
  I: Integer;
begin
  for I := 0 to FParams.Count - 1 do
    with FParams[I] do
      if not Bound then
      begin
        AssignField(DataSource.DataSet.FieldByName(Name));
        Bound := False;
      end;
end;

{ TIfxQuery.IProviderSupport }

procedure TIfxQuery.PSExecute;
begin
  ExecSQL;
end;

function TIfxQuery.PSGetParams: TParams;
begin
  Result := FParams;
end;

procedure TIfxQuery.PSSetCommandText(const CommandText: string);
begin
  if CommandText <> '' then
    SQL.Text := CommandText;
end;

procedure TIfxQuery.PSSetParams(AParams: TParams);
begin
  if AParams.Count <> 0 then
    FParams.Assign(AParams);
  Close;
end;

procedure TIfxQuery.GetDetailLinkFields(MasterFields, DetailFields: TList);

  function AddFieldToList(const FieldName: string; DataSet: TDataSet; List: TList): Boolean;
  var
    Field: TField;
  begin
    Field := DataSet.FindField(FieldName);
    if (Field <> nil) then
      List.Add(Field);
    Result := Field <> nil;
  end;

var
  I: Integer;
begin
  MasterFields.Clear;
  DetailFields.Clear;
  if (DataSource <> nil) and (DataSource.DataSet <> nil) then
    for I := 0 to FParams.Count - 1 do
      if AddFieldToList(FParams[I].Name, DataSource.DataSet, MasterFields) then
        AddFieldToList(FParams[I].Name, Self, DetailFields);
end;

procedure TIfxQuery.ParseMacroSQL;
begin
  IfxSQL.ParseMacroSQL;
end;

function TIfxQuery.ParamByName(const Value: string): TParam;
begin
  Result := FParams.ParamByName(Value);
end;

procedure TIfxQuery.Prepare;
begin
  Prepared := True;
end;

procedure TIfxQuery.Unprepare;
begin
  Prepared := False;
end;

function TIfxQuery.ExecSQL: int4;
begin
  CheckInactive;
  if DataLink.Active then
    SetMasterParams;
  Result := IfxSQL.Execute;
end;


end.